package com.gitee.aurora.core.rule;

import com.gitee.aurora.core.enums.OperateTypeEnums;
import com.gitee.aurora.core.utils.RulesResult;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class InvokeRules {

    public List<RulesResult> doInvoke(Map<String, Object> beanMap, Map<String, String> ruleMap) {
        try {
            List<RulesResult> rulesResultList = new ArrayList<>();
            for (String key : beanMap.keySet()) {
                String ruleStr = ruleMap.get(key);
                if (!StringUtils.isEmpty(ruleStr)) {
                    String args = null;
                    int enums;
                    if (ruleStr.contains("~")) {
                        String[] split = ruleStr.split("~");
                        args = split[1];
                        enums = Integer.parseInt(split[0]);
                    } else {
                        enums = Integer.parseInt(ruleStr);
                    }
                    String methodName = OperateTypeEnums.getMethodName(enums);

                    Class<? extends VerificationRules> verificationRulesClass = VerificationRules.class;
                    Method[] declaredMethods = verificationRulesClass.getDeclaredMethods();
                    for (Method declaredMethod : declaredMethods) {
                        assert methodName != null;
                        if (methodName.equals(declaredMethod.getName())) {
                            if (StringUtils.isEmpty(args)) {
                                args = OperateTypeEnums.getArgs(methodName);
                            }
                            Object invoke = declaredMethod.invoke(verificationRulesClass, beanMap.get(key), args);
                            String tip = InvokeRules.replaceTip((Boolean) invoke, methodName, args);
                            String status;
                            if ("success".equals(tip)) {
                                status = "0";
                            } else {
                                status = "1";
                            }
                            RulesResult rulesResult = new RulesResult(key, String.valueOf(beanMap.get(key)), tip, status);
                            rulesResultList.add(rulesResult);
                        }
                    }
                }
            }
            return rulesResultList;
        } catch (InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String replaceTip(Boolean invoke, String methodName, String args) {
        String tip = OperateTypeEnums.getTip(methodName);
        if (invoke) {
            tip = "success";
        }
        assert tip != null;
        if (tip.contains("{}")) {
            tip = tip.replace("{}", args);
        }
        return tip;
    }
}

